package com.agileai.portal.portlets.sso;

import java.io.IOException;
import java.security.Principal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.ProcessAction;
import javax.portlet.ReadOnlyException;
import javax.portlet.RenderMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ValidatorException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.pluto.container.PortletRequestContext;
import org.codehaus.jettison.json.JSONObject;
import org.mvel2.templates.TemplateRuntime;

import com.agileai.domain.DataRow;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.domain.FormSelect;
import com.agileai.portal.bizmoduler.sso.SSOTicket;
import com.agileai.portal.bizmoduler.sso.UserSSOService;
import com.agileai.portal.driver.GenericPotboyPortlet;
import com.agileai.portal.driver.PortletBean;
import com.agileai.portal.driver.Resource;
import com.agileai.portal.driver.common.PortletRequestHelper;
import com.agileai.portal.driver.common.PreferencesHelper;
import com.agileai.portal.driver.common.PreferencesWrapper;
import com.agileai.portal.driver.model.MenuBar;
import com.agileai.portal.driver.model.Theme;
import com.agileai.util.DateUtil;
import com.agileai.util.StringUtil;

public class SSORedirectPortlet  extends GenericPotboyPortlet{
	private String defaultHeight = "420";
	private String defaultWidth = "100%";
	private static final String LAST_ACESS_TIME_POST_FIX = "_LastAcessTimeKey";
	private static final String DynamicRetrieve = "DynamicRetrieve";
	
	protected Object lookupService(String serviceId) {
		Object service = BeanFactory.instance().getBean(serviceId);
		return service;
	}

	protected <ServiceType> ServiceType lookupService(Class<ServiceType> serviceClass) {
		String serviceId = buildServiceId(serviceClass);
		Object service = BeanFactory.instance().getBean(serviceId);
		return serviceClass.cast(service);
	}
	
	@SuppressWarnings("rawtypes")
	@RenderMode(name = "view")
	public void view(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletPreferences preferences = request.getPreferences();
		String userId = getUserId(request);
		String ssoAppId = preferences.getValue("ssoAppId", null);
		String targetURL = preferences.getValue("targetURL", null);		
		String height = preferences.getValue("height", "400");
		String width = preferences.getValue("width", null);
		String autoExtend = preferences.getValue("autoExtend",null);

		if (!StringUtil.isNullOrEmpty(ssoAppId) && !StringUtil.isNullOrEmpty(targetURL)
				&& !StringUtil.isNullOrEmpty(height) && !StringUtil.isNullOrEmpty(width)
				&& !StringUtil.isNullOrEmpty(autoExtend)
				){
			request.setAttribute("isSetting", "Y");
		}else{
			request.setAttribute("isSetting", "N");
		}
		
		String isSetting = (String)request.getAttribute("isSetting");
		if ("Y".equals(isSetting)){
			UserSSOService userSSOService = this.lookupService(UserSSOService.class);
			SSOTicket ssoTicket = userSSOService.findDummySSOTicket(ssoAppId);
			if (ssoTicket != null){
				SSOTicket.evalSSOTicket(ssoTicket,userId);
				long timeoutMinutes = ssoTicket.getTimeoutMinutes();
				
				boolean isSessionExpired = false;
				Date lastAcessTime = (Date)request.getPortletSession(true).getAttribute(ssoAppId+LAST_ACESS_TIME_POST_FIX, PortletSession.APPLICATION_SCOPE);
				if (lastAcessTime == null){
					isSessionExpired = true;
				}else{
					Date currentDate = new Date();
					long diffMinutes = DateUtil.getDateDiff(lastAcessTime, currentDate, DateUtil.MINUTE);
					if (diffMinutes >=  timeoutMinutes){
						isSessionExpired = true;
					}else{
						isSessionExpired = false;
					}
				}
				PortletBean portletBean = new PortletBean();
				portletBean.setAttribute("ssoTicket", ssoTicket);
				portletBean.setAttribute("isSessionExpired",String.valueOf(isSessionExpired));
				
				if (DynamicRetrieve.equals(targetURL)){
					HttpServletRequest httpServletRequest = PortletRequestHelper.getRequestContext(request).getServletRequest();
					String currentVirtualMenuId = httpServletRequest.getParameter(MenuBar.VIRTUAL_MENU_KEY);
					HttpSession session = httpServletRequest.getSession(false);
					HashMap<String,JSONObject> jsonMap = MenuBar.getMenuJSONObjectMap(session);
					JSONObject jsonObject = jsonMap.get(currentVirtualMenuId);
					try {
						String url = jsonObject.getString("url");
						targetURL = url;
					}catch(Exception e){
						e.printStackTrace();
					}
				}
				
				if (height != null && height.indexOf(Theme.ThemeBodyHeight) > -1){
					String template = height;
					HashMap vars = this.buildVarMap(request);
					height = String.valueOf(TemplateRuntime.eval(template, vars));
				}
				request.setAttribute("targetURL", targetURL);
				request.setAttribute("height", height);
				request.setAttribute("width", width);
				request.setAttribute("ssoAppId",ssoAppId);
				request.setAttribute("autoExtend", autoExtend);
				request.setAttribute("pageBean", portletBean);
			}
		}
		super.doView(request, response);
	}

	@SuppressWarnings({"rawtypes", "unchecked" })
	private HashMap buildVarMap(PortletRequest request){
		HashMap result = new HashMap();
		PortletRequestContext portletRequestContext = PortletRequestHelper.getRequestContext(request);
		HttpServletRequest httpRequest = portletRequestContext.getContainerRequest();
		HttpSession portalSession = httpRequest.getSession();
		Theme theme = (Theme)portalSession.getAttribute(Theme.class.getName());
		String height = (String)portalSession.getAttribute(Theme.WindowScreenHeight);
		String outherHeight = theme.getOuterHeight();
		String themeBodyHeight = String.valueOf(Integer.parseInt(height)- Integer.parseInt(outherHeight));
		result.put(Theme.ThemeBodyHeight, themeBodyHeight);
		return result;
	}
	
	@RenderMode(name = "edit")
	public void edit(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletPreferences preferences = request.getPreferences();
		UserSSOService userSSOService = this.lookupService(UserSSOService.class);
		String userId = getUserId(request);
		List<DataRow> records = userSSOService.findEditApplications(userId);
		FormSelect formSelect = new FormSelect();
		formSelect.setKeyColumnName("APP_ID");
		formSelect.setValueColumnName("APP_NAME");
		formSelect.putValues(records);
		
		String ssoAppId = preferences.getValue("ssoAppId", null);
		String targetURL = preferences.getValue("targetURL", null);		
		String height = preferences.getValue("height", defaultHeight);
		String width = preferences.getValue("width", defaultWidth);
		String autoExtend = preferences.getValue("autoExtend","Y");
		
		request.setAttribute("autoExtend", autoExtend);
		PortletBean portletBean = new PortletBean();
		portletBean.setAttribute("ssoAppId", formSelect.addSelectedValue(ssoAppId));
		portletBean.setAttribute("targetURL", targetURL);
		portletBean.setAttribute("height", height);
		portletBean.setAttribute("width", width);
		portletBean.setAttribute("autoExtend", autoExtend);
		request.setAttribute("pageBean", portletBean);

		super.doEdit(request, response);
	}

	@ProcessAction(name = "saveConfig")
	public void saveConfig(ActionRequest request, ActionResponse response) throws ReadOnlyException,
		PortletModeException, ValidatorException, IOException {
		PreferencesWrapper preferWapper = new PreferencesWrapper();		
		String ssoAppId = request.getParameter("ssoAppId");
		String targetURL = request.getParameter("targetURL");
		String height = request.getParameter("height");
		String width = request.getParameter("width");
		String autoExtend = request.getParameter("autoExtend");
		
		preferWapper.setValue("ssoAppId", ssoAppId);
		preferWapper.setValue("targetURL", targetURL);
		preferWapper.setValue("height", height);
		preferWapper.setValue("width", width);
		preferWapper.setValue("autoExtend", autoExtend);
		
		PreferencesHelper.savePublicPreferences(request, preferWapper.getPreferences());	
		response.setPortletMode(PortletMode.VIEW);
	}
	
	@ProcessAction(name = "cancelConfig")
	public void cancelConfig(ActionRequest request, ActionResponse response) throws ReadOnlyException,
		PortletModeException, ValidatorException, IOException {
		response.setPortletMode(PortletMode.EDIT);
	}
	@Resource(id="refreshLastAcessTime")
	public void refreshLastAcessTime(ResourceRequest request,ResourceResponse resourceResponse){
		String ssoAppId = request.getParameter("ssoAppId");
		request.getPortletSession(true).setAttribute(ssoAppId+LAST_ACESS_TIME_POST_FIX,new Date(), PortletSession.APPLICATION_SCOPE);
	}
	private String getUserId(PortletRequest request){
		String result = "";
		Principal principal = request.getUserPrincipal();
		if (principal != null){
			result = principal.getName();
		}
		return result;
	}
}
